﻿/*****************************************
 * This code is mostly written by peter  *
 * Necessary adjustment for Sims3Package *
 * Library is made.                      *
 * ***************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Sims3Package.Wrapper
{
    /// <summary>
    /// Wrapper for _KEY
    /// </summary>
    public class NameMapResourceWrapper :Wrapper
    {
        /// <summary>
        /// Used in refection for get types
        /// </summary>
        public new static List<UInt32> ResourceTypes { get { return new List<uint>(mResourceTypes); } }
        private new static UInt32[] mResourceTypes = { 0x0166038CU };
        /// <summary>
        /// Dictionary contains the stbl table
        /// </summary>
        [WrapperVisible(true)]
        public Dictionary<UInt64, string> NameMap { get; set; }
        private uint version = 1;
        /// <summary>
        /// Standard constructor
        /// </summary>
        /// <param name="s">Stream that contained in entry, null to represent new resource</param>
        public NameMapResourceWrapper(Stream s)
            : base(s)
        {
            stream = s; Parse();
        }

        private void Parse()
        {
            NameMap = new Dictionary<ulong, string>();
            if (stream == null || stream.Length < 1) return;
            stream.Position = 0;
            BinaryReader br = new BinaryReader(stream);
            
            version = br.ReadUInt32();
            if (version != 1)
                throw new InvalidDataException(String.Format("{0}: unsupported 'version'.  Read '0x{1:X8}', supported: '0x00000001'", this.GetType().Name, version));


            for (int i = br.ReadInt32(); i > 0; i--)
                NameMap.Add(br.ReadUInt64(), Encoding.UTF8.GetString(br.ReadBytes(br.ReadInt32())));

            if (stream.Position != stream.Length)
                throw new InvalidDataException(String.Format("{0}: Length {1} bytes, parsed {2} bytes", this.GetType().Name, stream.Length, stream.Position));
        }
        /// <summary>
        /// Returns the stream written into entry
        /// </summary>
        /// <returns>Stream.IO.Stream</returns>
        public override Stream UnParse()
        {
            if (this.NameMap == null) return null;
            MemoryStream ms = new MemoryStream();
            BinaryWriter w = new BinaryWriter(ms);
            w.Write(version);
            w.Write(NameMap.Count);
            foreach (KeyValuePair<ulong, string> kvp in this.NameMap)
            {
                w.Write(kvp.Key);
                w.Write(kvp.Value.Length);
                w.Write(kvp.Value.ToCharArray());
            }
            w.Flush();
            ms.Position = 0;
            return ms;
        }
        /// <summary>
        /// Used in text preview
        /// </summary>
        public override string Value
        {
            get
            {
                if (this.NameMap == null) return string.Empty;
                StringBuilder b = new StringBuilder();
                long count = 0;
                foreach (var kvp in this.NameMap)
                {
                    b.AppendFormat("[{0:X}] Instance: 0x{1} Name: {2}", count++, kvp.Key.ToString("X").PadLeft(16, '0'), kvp.Value).AppendLine();
                }
                return b.ToString();
            }
        }

    }
}
